<template>
	<div class="default-main">

		<cus-form id="item-form" collapsable icon="fa fa-search" label="搜索">
			<template #title-after>
				<el-button icon="el-icon-Search" size="small" type="primary" @click.stop="handleSearch">
					搜索
				</el-button>
				<el-button icon="el-icon-Refresh" size="small" type="primary" @click.stop="resetSearch">
					重置
				</el-button>
			</template>
			<template #form>
				<el-form ref="itemSearchForm" :model="params" label-width="auto">
					<el-row :gutter="20" justify="start">
						<el-col :span="8">
							<el-form-item label="物品名称">
								<el-input v-model="params.itemName_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="类别">
								<el-cascader
										v-model="params.classificationIdList"
										:options="classificationOptionList"
										:props="{ expandTrigger: 'hover', checkStrictly: false, multiple: true, emitPath: false }"
										:show-all-levels="false"
										clearable
										collapse-tags
										collapse-tags-tooltip
										filterable
										placeholder="不限"
										@change="classificationIdListChanged"
								></el-cascader>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="物理形态">
								<business-code-radio v-model="params.fluid_eq" border code-type="physicalForm" @change="handleSearch"/>
							</el-form-item>
						</el-col>
					</el-row>
					<el-row :gutter="20" justify="space-between">
						<el-col :span="8">
							<el-form-item label="能量不小于">
								<el-input v-model="params.energy_ge" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable controls-position="right"
								          step-strictly
								          type="number" @change="handleSearch">
									<template #append>MJ</template>
								</el-input>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="资源槽点数不小于">
								<el-input v-model="params.resourceSinkPoints_ge" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable
								          controls-position="right"
								          step-strictly type="number" @change="handleSearch"/>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="伤害不小于">
								<el-input v-model="params.damage_ge" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable controls-position="right"
								          step-strictly
								          type="number" @change="handleSearch"/>
							</el-form-item>
						</el-col>
					</el-row>
					<el-row :gutter="20" justify="start">
						<el-col :span="8">
							<el-form-item label="能否手搓">
								<business-code-radio v-model="params.handmade_eq" border code-type="handmade" @change="handleSearch"/>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="装备部位">
								<business-code-select v-model="params.equipmentLocation_eq" :filterable="false" clearable code-type="equipmentLocation" filterable
								                      placeholder="不限" @change="handleSearch"/>
							</el-form-item>
						</el-col>
						<el-col :span="8">
							<el-form-item label="物品描述">
								<el-input v-model="params.description_like" clearable placeholder="模糊查询" @keyup.enter="handleSearch"></el-input>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</template>
		</cus-form>

		<cus-table-title id="item-table-title" icon="local-cus-item" label="物品">
			<template #after>
				<el-button v-if="isAdmin()" icon="el-icon-Plus" size="small" style="margin-left: 20px" type="primary" @click="toAdd">
					新增
				</el-button>
			</template>
		</cus-table-title>
		<el-table ref="tableRef" v-loading="tableLoading" :data="itemTableData" :header-cell-class-name="handleHeaderCellClass" :max-height="tableMaxHeight" border
		          class="cus-table" fit highlight-current-row @sort-change="elTableSortChange($event, params.orderby, handleSearch)">
			<el-table-column align="center" label="序号" width="60">
				<template v-slot="scope">
					{{ initTableIndex(pageRef, scope.$index) }}
				</template>
			</el-table-column>
			<el-table-column align="center" label="名称" min-width="200" prop="itemName"></el-table-column>
			<el-table-column align="center" label="图片" width="150">
				<template v-slot="scope">
					<el-image v-if="scope.row.image" :src="getImage(scope.row.image)" fit="contain"
					          style="width: 100px; height: 100px;cursor: pointer" @click="toUpdate(scope.row)"
					></el-image>
				</template>
			</el-table-column>
			<el-table-column v-if="isAdmin()" align="center" label="同级排序" prop="sort" width="90"></el-table-column>
			<el-table-column align="center" label="类别" prop="classificationName" sort-by="classificationId" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag>{{ scope.row.classificationName || '/' }}</el-tag>
				</template>
			</el-table-column>
			<!--			<el-table-column align="center" label="物理形态" prop="fluid" sortable="custom" width="150">-->
			<!--				<template v-slot="scope">-->
			<!--					<el-tag>{{ getBusinessCodeName('physicalForm', scope.row.fluid) }}</el-tag>-->
			<!--				</template>-->
			<!--			</el-table-column>-->
			<!--			<el-table-column align="center" label="装备部位" prop="equipmentLocation" sortable="custom" width="150">-->
			<!--				<template v-slot="scope">-->
			<!--					<el-tag v-if="scope.row.equipmentLocation === 0" type="info">/</el-tag>-->
			<!--					<el-tag v-else>{{ getBusinessCodeName('equipmentLocation', scope.row.equipmentLocation) }}</el-tag>-->
			<!--				</template>-->
			<!--			</el-table-column>-->
			<el-table-column align="center" label="能量" prop="energy" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag v-if="scope.row.energy === -1" type="info">/</el-tag>
					<el-tag v-else>{{ scope.row.energy }}&nbsp;MJ</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="资源槽点数" prop="resourceSinkPoints" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag v-if="scope.row.resourceSinkPoints === -1" type="info">/</el-tag>
					<el-tag v-else>{{ scope.row.resourceSinkPoints }}</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="伤害" prop="damage" sortable="custom" width="150">
				<template v-slot="scope">
					<el-tag v-if="scope.row.damage === -1" type="info">/</el-tag>
					<el-tag v-else>{{ scope.row.damage }}</el-tag>
				</template>
			</el-table-column>
			<el-table-column align="center" label="描述" min-width="450" prop="description">
				<template v-slot="scope">
					<div class="pre-wrap">{{ scope.row.description }}</div>
				</template>
			</el-table-column>
			<el-table-column :label="String($t('table.actions'))" :width="isAdmin() ? 200 : 150" align="center" fixed="right">
				<template v-slot="scope">
					<div class="cus-center">
						<el-dropdown @command="handleCommand">
							<el-button size="small" type="primary">
								配方
								<icon class="el-icon--right" name="el-icon-ArrowDown"></icon>
								<template #icon>
									<icon name="local-cus-recipe"></icon>
								</template>
							</el-button>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item :command="{type: 'asProduct', data: scope.row}">
										作为产物
									</el-dropdown-item>
									<el-dropdown-item :command="{type: 'asMaterial', data: scope.row}">
										作为原料
									</el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
						<el-dropdown v-if="isAdmin()" style="margin-left: 10px">
							<el-button icon="el-icon-MoreFilled" plain round size="small"></el-button>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item :disabled="!hasPermission('g-item:saveItem')" icon="el-icon-Edit" @click="toUpdate(scope.row)">
										编辑
									</el-dropdown-item>
									<el-dropdown-item :disabled="!hasPermission('g-item:deleteItem')" icon="el-icon-Delete" @click="deleteItem(scope.row)">
										删除
									</el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
					</div>
				</template>
			</el-table-column>
		</el-table>
		<cus-pagination id="item-pagination" ref="pageRef" v-model="itemTableData" v-model:loading="tableLoading" :pageSize="10" :params="params"
		                url="/game/g-item/readOnly/searchItemByPage"/>

		<!-- 对话框（新增、修改） -->
		<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :close-on-press-escape="true" :title="dialogTitle"
		           append-to-body center class="cus-dialog" destroy-on-close draggable width="50%">
			<div v-if="itemImage" class="cus-center" style="padding-bottom: 20px">
				<el-image :src="getImage(itemImage)" fit="contain" style="width: 128px; height: 128px"></el-image>
			</div>
			<el-form ref="editFormRef" :disabled="!hasPermission('g-item:saveItem')" :model="item" :rules="rules" label-width="auto">
				<el-form-item label="物品名称" prop="itemName">
					<el-input v-model="item.itemName" clearable maxlength="100"></el-input>
				</el-form-item>
				<el-form-item label="物品描述" prop="description">
					<el-input v-model="item.description" :autosize="{ minRows: 4, maxRows: 4}" clearable maxlength="500" type="textarea"></el-input>
				</el-form-item>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="类别" prop="classificationId">
							<el-cascader
									v-model="item.classificationId"
									:options="classificationOptionList"
									:props="{ expandTrigger: 'hover', checkStrictly: false, emitPath: false }"
									:show-all-levels="true"
									clearable
									filterable
							></el-cascader>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="同级排序" prop="sort">
							<el-input-number v-model="item.sort" :min="0" :step="1" class="w100" controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="物理形态" prop="fluid">
							<business-code-radio v-model="item.fluid" border code-type="physicalForm"/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="最大堆叠数量" prop="stack">
							<el-input-number v-model="item.stack" :max="MAX_INTEGER" :min="1" :step="1" class="w100" clearable controls-position="right"
							                 step-strictly/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="能量（MJ）" prop="energy">
							<el-input-number v-model="item.energy" :max="MAX_INTEGER" :min="-1" :step="1" class="w100" clearable
							                 controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="资源槽点数" prop="resourceSinkPoints">
							<el-input-number v-model="item.resourceSinkPoints" :max="MAX_INTEGER" :min="-1" :step="1" class="w100" clearable
							                 controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="伤害" prop="damage">
							<el-input-number v-model="item.damage" :max="MAX_INTEGER" :min="-1" :step="1" class="w100" clearable
							                 controls-position="right" step-strictly/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row :gutter="20" justify="start">
					<el-col :span="8">
						<el-form-item label="能否手搓" prop="handmade">
							<el-switch v-model="item.handmade" :active-value="1" :inactive-value="0"/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item label="能否装备" prop="equippable">
							<el-switch v-model="item.equippable" :active-value="1" :inactive-value="0" @change="equippableChanged"/>
						</el-form-item>
					</el-col>
					<el-col :span="8">
						<el-form-item v-if="item.equippable === 1" label="装备位置" prop="equipmentLocation">
							<business-code-select v-model="item.equipmentLocation" :hide-value-array="['0']" code-type="equipmentLocation"/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-form-item label="图片地址" prop="image">
					<el-input v-model="item.image" clearable maxlength="500"></el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<el-button v-auth="'g-item:saveItem'" icon="el-icon-CircleCheck" type="primary" @click="save">
					保存
				</el-button>
				<el-button icon="el-icon-CircleClose" type="warning" @click="dialogVisible = false">
					取消
				</el-button>
			</template>
		</el-dialog>

	</div>
</template>

<script lang="ts" name="Item" setup>

import {onActivated, onMounted, reactive, ref} from 'vue'
import type {FormInstance, FormRules, TableColumnCtx, TableInstance} from 'element-plus'
import {ElMessageBox} from 'element-plus'
import {deleteItemApi, getItemCascadeClassificationApi, saveItemApi} from '@/api/gameData/item.api'
import {elTableHeaderCellClassName, elTableSortChange, focusFormErrorElement, getImage, initTableIndex, messageSuccess} from '@/utils/commonUtil'
import {useI18n} from 'vue-i18n'
import CusPagination from '@/components/cus-pagination.vue'
import CusTableTitle from '@/components/cus-table-title.vue'
import {calcMaxHeight} from '@/utils/layoutUtil'
import {debounce, type DebouncedFunc} from 'lodash-es'
import {useEventListener} from '@vueuse/core'
import {onBeforeRouteLeave} from 'vue-router'
import BusinessCodeSelect from '@/components/business-code-select.vue'
import Icon from '@/components/icon.vue'
import router from '@/router'
import BusinessCodeRadio from '@/components/business-code-radio.vue'
import {MAX_INTEGER} from '@/utils/constantsUtil'
import {hasPermission, isAdmin} from '@/utils/authUtil'
import {useRouteParamsStore} from '@/stores/modules/routeParams.store'
import CusForm from '@/components/cus-form.vue'

interface DropdownCommand {
	type: 'asProduct' | 'asMaterial'
	data: GItem
}

const {t} = useI18n()
const routeParamsStore = useRouteParamsStore()

const pageRef = ref()
const editFormRef = ref<FormInstance>()
const tableRef = ref<TableInstance>()

const tableMaxHeight = ref<number>(800)
const params = reactive<SearchItemRequest>({
	itemName_like: undefined,
	classificationIdList: [],
	fluid_eq: undefined,
	equipmentLocation_eq: undefined,
	description_like: undefined,
	energy_ge: undefined,
	resourceSinkPoints_ge: undefined,
	damage_ge: undefined,
	handmade_eq: undefined,
	orderby: []
})
const tableLoading = ref(false)
const itemTableData = ref<GItem[]>([])
const classificationOptionList = ref<CascadeClassificationVo[]>([])
const item = reactive<GItem>({
	id: undefined,
	itemName: undefined,
	description: undefined,
	fluid: undefined,
	stack: undefined,
	energy: -1,
	resourceSinkPoints: -1,
	damage: -1,
	equipmentLocation: undefined,
	handmade: undefined,
	image: undefined,
	classificationId: undefined,
	sort: 0
})
const itemImage = ref<string>()
const dialogTitle = ref<string>()
const dialogVisible = ref(false)
const rules = reactive<FormRules>({
	itemName: [
		{required: true, message: '请输入物品名称', trigger: 'change'}
	],
	description: [
		{required: true, message: '请输入物品描述', trigger: 'change'}
	],
	fluid: [
		{required: true, message: '请选择物理形态', trigger: 'change'}
	],
	stack: [
		{required: true, message: '请输入最大堆叠数量', trigger: 'change'}
	],
	energy: [
		{required: true, message: '请输入能量', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'number'}
	],
	resourceSinkPoints: [
		{required: true, message: '请输入资源槽点数', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'number'}
	],
	damage: [
		{required: true, message: '请输入伤害值', trigger: 'change', min: -1, max: MAX_INTEGER, type: 'number'}
	],
	equippable: [
		{required: true, message: '请选择能否装备', trigger: 'change'}
	],
	equipmentLocation: [
		{required: true, message: '请选择装备位置', trigger: 'change'}
	],
	handmade: [
		{required: true, message: '请选择能否手搓', trigger: 'change'}
	],
	sort: [
		{required: true, message: '请输入同级排序', trigger: 'change'}
	],
	classificationId: [
		{required: true, message: '请选择类别', trigger: 'change'}
	]
})

/**
 * 计算表格最大高度
 */
const getTableMaxHeight: DebouncedFunc<() => typeof getTableMaxHeight> = debounce(() => {
	tableMaxHeight.value = calcMaxHeight('#item-form', '#item-table-title', '#item-pagination')
	return getTableMaxHeight
}, 100, {
	leading: true,
	trailing: false,
	maxWait: 100
})

const handleHeaderCellClass = (args: { rows: GItem[], column: TableColumnCtx<GItem>, rowIndex: number, columnIndex: number }) => {
	elTableHeaderCellClassName(args, params.orderby)
}

const classificationIdListChanged = (value: number[]) => {
	if (value && value.length === 1) {
		params.orderby.push({
			field: 'sort',
			order: 'ascending'
		})
	} else {
		params.orderby = params.orderby.filter(item => item.field !== 'sort')
	}
	handleSearch()
}

const handleSearch = () => {
	pageRef.value!.reload()
}

const resetParams = () => {
	params.itemName_like = undefined
	params.classificationIdList = []
	params.fluid_eq = undefined
	params.equipmentLocation_eq = undefined
	params.description_like = undefined
	params.energy_ge = undefined
	params.resourceSinkPoints_ge = undefined
	params.damage_ge = undefined
	params.handmade_eq = undefined
	params.orderby = []
	// 清除多列的排序状态
	for (const column of tableRef.value?.store.states.columns.value) {
		column.order = null
	}
}

const resetSearch = () => {
	resetParams()
	handleSearch()
}

const resetItem = () => {
	item.id = undefined
	item.itemName = undefined
	item.description = undefined
	item.fluid = undefined
	item.stack = undefined
	item.energy = -1
	item.resourceSinkPoints = -1
	item.damage = -1
	item.equippable = undefined
	item.equipmentLocation = undefined
	item.handmade = undefined
	item.image = undefined
	item.classificationId = undefined
	item.sort = 0
}

const handleCommand = (command: DropdownCommand) => {
	switch (command.type) {
		case 'asProduct':
			routeParamsStore.setParams({
				productItemId: command.data.id
			}, 'Recipe')
			router.push({name: 'Recipe'})
			break
		case 'asMaterial':
			routeParamsStore.setParams({
				materialItemId: command.data.id
			}, 'Recipe')
			router.push({name: 'Recipe'})
			break
	}
}

const toAdd = () => {
	resetItem()
	itemImage.value = undefined
	dialogVisible.value = true
	dialogTitle.value = '新增物品'
}

const toUpdate = (row: GItem) => {
	resetItem()
	Object.assign(item, JSON.parse(JSON.stringify(row)))
	itemImage.value = item.image
	dialogVisible.value = true
	dialogTitle.value = '编辑物品信息'
}

const save = () => {
	editFormRef.value!.validate(isValid => {
		if (isValid) {
			saveItemApi(item).then(() => {
				if (item.id) {
					messageSuccess(t('successMessage.update'))
				} else {
					messageSuccess(t('successMessage.add'))
				}
				dialogVisible.value = false
				pageRef.value!.buildData()
			})
		} else {
			focusFormErrorElement()
		}
	})
}

const deleteItem = (row: GItem) => {
	ElMessageBox.confirm(row.itemName, '删除该物品？', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
		draggable: true
	}).then(() => {
		deleteItemApi(row.id!).then(() => {
			messageSuccess(t('successMessage.delete'))
			pageRef.value!.buildData()
		})
	}).catch(() => {
	})
}

const equippableChanged = () => {
	item.equipmentLocation = undefined
}

// 物品类别
getItemCascadeClassificationApi().then(response => {
	classificationOptionList.value = response.data
})

onMounted(() => {
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

// 该页面开启缓存且首次或后续进入时执行，刷新页面不执行
onActivated(() => {
	useEventListener(window, 'resize', getTableMaxHeight()!)
})

onBeforeRouteLeave(() => {
	window.removeEventListener('resize', getTableMaxHeight)
})

</script>

<style lang="scss" scoped>
</style>
